练习

1.(*1)写出下面的声明:一个函数,它以指向字符的指针和对整数的引用为参数,不返回值;一个指向这个函数的指针;一个以这种指针为参数的函数;以及一个返回这种指针的函数。写出一个函数的定义,它以一个这样的指针作为参数,并返回其参数作为返回值。提示:使用typedef。

2.(*1)下面的代码是什么意思?它会有什么用处?

typedef int (&rifii)(int, int);

3.(*1.5)写出一个类似“Hello,world!”的函数,它以一个名字作为命令行参数,并写出“Hello,name”(其中name是实际的命令行参数)。修改这个程序,使它能以一系列名字作为参数,并对每个名字分别说hello。

4.(*1.5)写一个程序,它读入任意多个由命令行参数提供名字的文件,并将它们一个接着一个写入cout。因为这个程序拼接起它的输入去产生输出,你可以称它为cat。

5.(*2)将一个小的C程序转换为C++程序。修改头文件,声明所有的函数调用,并声明所有的参数类型。只要可能,就把#define换成enum、const或者inline。从.c文件里删除所有的extern声明。如果有必要的话,将所有的函数定义转换为C++的函数定义语法。将所有对malloc()和free()的调用替换为new和delete。删除不必要的强制。

6.(*2)用更高效的排序算法实现ssort()(7.7节)。提示:qsort()。

7.(*2.5)考虑:

struct Tnode {
    string word;
    int count;
    Tnode* left;
    Tnode* right;
};

写一个函数向Tnode的树中插入新的单词。写一个函数将Tnode的树打印出来。写一个函数将Tnode的树按照单词的字典顺序打印出来。修改Tnode,使得它只存储一个到任意长的单词的指针,该单词存储在一个由new分配的字符数组里。修改上述函数,使它们使用新的Tnode。

8.(*2.5)写一个函数求二维数组的逆。提示:C.7节。

9.(*2)写一个加密程序,它从cin读入,并将编码后的字符序列写到cout。你可以采用如下的简单加密模式:字符c的加密形式是c ^ key[i],其中key是通过命令行参数提供的一个字符串。这个程序以循环的方式使用key中的字符,直到读完全部输入。用同一个key重新加密编码后的正文就能得到原来的正文。如果不提供key(即提供空字符串),则不做加密。

10.(*3.5)写一个程序来帮助在不知道key的情况下解密采用7.10[9]的方式加密的消息。提示:參看David Kahn,《The Codebreaker》,Macmillian,1967,New York,207~213页。

11.(*3)写一个error函数,它取一个printf风格的包含%s、%c和%d指示符的格式串,以及任意多个其他参数。请不要使用printf()。如果你不知道%s、%c和%d的意思,请参看21.8节。使用<cstdarg>

12.(*1)你怎样为指向函数的指针类型选择typedef所定义的名字?

13.(*2)看一些程序,以便取得对实际程序中名字使用的各种风格的一些认识。大写字母如何用?下划线符如何用?什么时候使用如i和x这样的短名字?

14.(*1)下面这些宏定义各有什么毛病?

#define PI = 3.141593;
#define MAX(a,b) a>b?a:b
#define fac(a) (a)*fac((a)-1)

15.(*3)写一个宏处理器,它能够定义和展开简单的宏(像C预处理器那样)。它从cin读并向cout写。开始时请不要去处理带参数的宏。提示:桌面计算器(6.1节)包含一个符号表和一个词法分析器,你可以修改它们。

16.(\2)实现7.5节的print()。

17.(*2)给6.1节的桌面计算器增加函数,例如sqrt()、log()和sin()。提示:预先定义一些名字,通过一个指向函数的指针的数组调用这些函数。不要忘记对于函数调用检查参数的类型。

18.(*1)写一个不用递归的阶乘函数。参见11.14[6]。

19.(*2)写一个函数,实现为5.9[13]定义的Date加上一天、一个月、一年的功能。写一个函数对于所给的Date给出对应的星期几。写一个函数给出参数Date之后第一个星期一对应的Date。

🔚